/**
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.googlecode.chigscommons.web.common.brix.plugin.menuml;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import org.apache.wicket.model.IDetachable;

import brix.jcr.api.JcrNodeIterator;
import brix.jcr.wrapper.BrixNode;
import brix.web.reference.Reference;

public class MenuMultiLang implements IDetachable {

    public static class Entry implements IDetachable {
        private final Entry parent;

        public Entry(Entry parent)
        {
            this.parent = parent;
        }

        public Entry getParent()
        {
            return parent;
        }

        private final List<ChildEntry> children = new ArrayList<ChildEntry>();

        public List<ChildEntry> getChildren()
        {
            return children == null ? new ArrayList<ChildEntry>() : children;
        }

        public void detach()
        {
            for (ChildEntry entry : children)
            {
                entry.detach();
            }
        }
    };

    public static class RootEntry extends Entry {
        public RootEntry() {
            super(null);
        }

        @Override
        public String toString() {
            return "MenuMultiLang Root";
        }
        
        public String getTitle() {
        	return "MenuMultiLang Root";
        }
        
        public Reference getReference() {
        	return null;
        }
        
        public String getCssClass() {
        	return null;
        }
    };

    public static class ChildEntry extends Entry {

        public ChildEntry(Entry parent) {
            super(parent);
        }

        // Titel in der Default Sprache
        private String title;
        // Titel in einer weiteren Sprache
        private String titleOther;
        
        private Reference reference;
        private String cssClass;

        public String getTitle()
        {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public String getTitleOther() {
			return titleOther;
		}

		public void setTitleOther(String titleOther) {
			this.titleOther = titleOther;
		}

		public Reference getReference() {
            return reference;
        }

        public void setReference(Reference reference) {
            this.reference = reference;
        }

        public String getCssClass() {
            return cssClass;
        }

        public void setCssClass(String cssClass) {
            this.cssClass = cssClass;
        }

        @Override
        public void detach() {
            super.detach();
            if (reference != null)
            {
                reference.detach();
            }
        }

        @Override
        public String toString() {
            return getTitle();
        }
    }

    private RootEntry root = new RootEntry();

    public RootEntry getRoot() {
        return root;
    }

    public void detach() {
        root.detach();
    }

    private String name;

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    private Locale otherLocale;
    
    public Locale getOtherLocale() {
		return otherLocale;
	}

	public void setOtherLocale(Locale otherLocale) {
		this.otherLocale = otherLocale;
	}

	private void saveEntry(BrixNode node, Entry entry) {
        if (entry instanceof ChildEntry) {
            ChildEntry childEntry = (ChildEntry)entry;
            node.setProperty("title", childEntry.getTitle());
            node.setProperty("titleOther", childEntry.getTitleOther());
            node.setProperty("cssClass", childEntry.getCssClass());
            if (childEntry.getReference() != null) {
                childEntry.getReference().save(node, "reference");
            }
        }
        for (Entry e : entry.getChildren()) {
            BrixNode child = (BrixNode)node.addNode("child");
            saveEntry(child, e);
        }
    }

    public void save(BrixNode node) {
        if (!node.isNodeType("mix:referenceable")) {
            node.addMixin("mix:referenceable");
        }
        // The Config part
        node.setProperty("name", getName());
        node.setProperty("otherLocale", getOtherLocale().toString());
        
        if (node.hasNode("menuml")) {
            node.getNode("menuml").remove();
        }
        BrixNode menu = (BrixNode)node.addNode("menuml", "nt:unstructured");
        saveEntry(menu, getRoot());
    }

    public void loadConfig(BrixNode node) {
        if (node.hasProperty("name")) {
            setName(node.getProperty("name").getString());
        }
		if (node.hasProperty("otherLocale")) {
			String lang = node.getProperty("otherLocale").getString();
			String[] parts = lang.split("_");
			switch (parts.length) {
			case 1:
				setOtherLocale(new Locale(parts[0]));
				break;
			case 2:
				setOtherLocale(new Locale(parts[0], parts[1]));
				break;
			default:
				setOtherLocale(new Locale(parts[0], parts[1], parts[2]));
				break;
			}
		}
    }

    private void loadChildEntry(BrixNode node, ChildEntry entry) {
        if (node.hasProperty("title")) {
            entry.setTitle(node.getProperty("title").getString());
        }
        if (node.hasProperty("titleOther")) {
            entry.setTitleOther(node.getProperty("titleOther").getString());
        }
        entry.setReference(Reference.load(node, "reference"));
        if (node.hasProperty("cssClass")) {
            entry.setCssClass(node.getProperty("cssClass").getString());
        }
    }

    private void loadEntry(BrixNode node, Entry entry) {
        JcrNodeIterator i = node.getNodes("child");
        while (i.hasNext()) {
            BrixNode child = (BrixNode)i.nextNode();
            ChildEntry e = new ChildEntry(entry);
            loadChildEntry(child, e);
            loadEntry(child, e);
            entry.getChildren().add(e);
        }
    }

    public void loadMenu(BrixNode node) {
        root = new RootEntry();
        if (node.hasNode("menuml")) {
            loadEntry((BrixNode)node.getNode("menuml"), root);
        }
    }

    public void load(BrixNode node) {
        loadConfig(node);
        loadMenu(node);
    }
}
